﻿SSVC.Wrap.Dojo.SetObject("SSVC.ArasHelper", (function()
{
	var SecureMessageItem = function(action)
	{
		var secureMessageItm = top.aras.IomInnovator.newItem("Secure Message", action);

		secureMessageItm.itemStructure = null;

		secureMessageItm.fill = function()
		{
			var result = secureMessageItm.apply();

			secureMessageItm.dom = result.dom;
			secureMessageItm.node = result.node;
			secureMessageItm.nodeList = result.nodeList;
		};

		secureMessageItm.applyFilter = function(filter)
		{
			if (!filter) throw new Error("Inner error: SecureMessageItem applyFilter - filter param can't be undefined");
			addFilter(filter);
		}

		secureMessageItm.buildStructure = function(etChilds, childsCount)
		{
			secureMessageItm.itemStructure = secureMessageItm.toArray();
			buildStructure(etChilds, childsCount);
		};

		secureMessageItm.toArray = function()
		{
			var arr = [];
			for (var i = 0; i < secureMessageItm.getItemCount() ; i++)
			{
				arr.push(secureMessageItm.getItemByIndex(i));
			}
			return arr;
		};

		secureMessageItm.sort = function(sortby)
		{
			if (!sortby)
				sortby = SSVC.Utils.Enums.SortMode.Date;
			switch (sortby)
			{
				case SSVC.Utils.Enums.SortMode.FirstName:
					secureMessageItm.itemStructure.sort(sortMessagesByFirstName);
					break;
				case SSVC.Utils.Enums.SortMode.LastName:
					secureMessageItm.itemStructure.sort(sortMessagesByLastName);
					break;
				case SSVC.Utils.Enums.SortMode.Message:
					secureMessageItm.itemStructure.sort(sortMessagesByMessage);
					break;
				case SSVC.Utils.Enums.SortMode.Conversation:
					secureMessageItm.itemStructure.sort(sortMessagesByConversation);
					break;
				case SSVC.Utils.Enums.SortMode.Date:
					secureMessageItm.itemStructure.sort(sortMessagesByDate);
					break;
			}
		};

		secureMessageItm.setItemBeforeSaving = function(object)
		{
			/*
			*object.classification
			*object.from_identity
			*object.markup
			*object.message_text
			*object.parent_id
			*object.snapshot
			*object.source_id
			*object.source_major_rev
			*object.source_generation
			*object.source_state
			*object.thumbnail
			*object.view_state			
			*/
			secureMessageItm.setAttribute("select", "classification, parent_id, message_text, from_identity, to_identity, sent, thumbnail, snapshot, source_major_rev, source_generation, source_state, source_id, markup, history_item, last_reply_sent, children_count");
			secureMessageItm.setProperty("classification", object.classification);
			secureMessageItm.setProperty("from_identity", object.from_identity);
			secureMessageItm.setProperty("message_text", object.message_text);
			secureMessageItm.setProperty("parent_id", object.parent_id || "");
			secureMessageItm.setProperty("source_id", object.source_id);
			secureMessageItm.setProperty("source_major_rev", object.source_major_rev);
			secureMessageItm.setProperty("source_generation", object.source_generation);
			secureMessageItm.setProperty("source_state", object.source_state);
			if (object.classification == "Markup")
			{
				secureMessageItm.setProperty("markup", object.markup);
				secureMessageItm.setProperty("snapshot", object.snapshot);
				secureMessageItm.setProperty("thumbnail", object.thumbnail);
				secureMessageItm.setProperty("view_state", object.view_state);
			}
		};

		function addFilter(filter)
		{
			if (!filter) return;
			var doc = secureMessageItm.dom;

			for (var i = 0; i < filter.length; i++)
			{
				var parentNode = secureMessageItm.node;
				if (SSVC.Utils.isNotNullOrUndefined(filter[i].itemProperty))
					parentNode = parentNode.selectSingleNode("/AML/Item/" + filter[i].itemProperty + "/Item");
				parentNode.appendChild(createFilterAmlForCondition(filter[i]));
			}

			function createFilterAmlForCondition(record)
			{
				var conditionArr = record.text.split(/\s+/);
				if (conditionArr.length == 1)
					return createFilterTag(record);

				var andIndex = 999, notIndex = 1000, orIndex = 499;

				var parsedTree = [];
				var nodePar;
				var index = 0;
				while (index < conditionArr.length)
				{
					if (conditionArr[index] == "not")
					{
						nodePar = doc.createElement("not");
						nodePar.appendChild(createFilterTag({ name: record.name, text: conditionArr[index + 1], condition: record.condition }));
						parsedTree.push(
							{
								node: nodePar,
								operation: null,
								priority: null
							});

						index = index + 2;
						continue;
					}

					if (conditionArr[index] == "and")
					{
						parsedTree[parsedTree.length - 1].operation = "and";
						parsedTree[parsedTree.length - 1].priority = andIndex = andIndex - 1;

						index++;
						continue;
					}

					if (conditionArr[index] == "or")
					{
						parsedTree[parsedTree.length - 1].operation = "or";
						parsedTree[parsedTree.length - 1].priority = orIndex = orIndex - 1;

						index++;
						continue;
					}

					nodePar = createFilterTag({ name: record.name, text: conditionArr[index], condition: record.condition });
					parsedTree.push(
						{
							node: nodePar,
							operation: null,
							priority: null
						});

					index++;
					continue;
				}
				while (parsedTree.length > 1)
				{
					index = indexOfBiggestPriority(parsedTree);
					nodePar = doc.createElement(parsedTree[index].operation);
					nodePar.appendChild(parsedTree[index].node);
					nodePar.appendChild(parsedTree[index + 1].node);

					parsedTree[index].node = nodePar;
					parsedTree[index].operation = parsedTree[index + 1].operation;
					parsedTree[index].priority = parsedTree[index + 1].priority;

					parsedTree.splice(index + 1, 1);
				}

				return parsedTree[0].node;

				function indexOfBiggestPriority(array)
				{
					var index = 0, max = array[0].priority;
					for (var i = 1; i < array.length; i++)
					{
						if (array[i].priority > max)
						{
							max = array[i].priority;
							index = i;
						}
					}

					return index;
				}
			}

			function createFilterTag(cond)
			{
				var newTag = doc.createElement(cond.name);
				newTag.text = cond.text;
				if (SSVC.Utils.isNotNullOrUndefined(cond.condition))
					newTag.setAttribute("condition", cond.condition);

				return newTag;

			}
		}

		function buildStructure(getChilds, childsCount)
		{
			for (var i = 0; i < secureMessageItm.itemStructure.length ; i++)
			{
				var parent = secureMessageItm.itemStructure[i];
				parent.parentId = parent.getPropertyItem("parent_id");
				parent.identityItem = parent.getPropertyItem("from_identity");
				parent.sourceCommunityId = parent.getProperty("source_id");
				if (parent.sourceCommunityId != undefined)
				{
					var communityItm = SecureMessageItem.CommunityItem.getById(parent.sourceCommunityId);
					parent.fileItm = communityItm.fileItm;
					parent.relatedItm = communityItm.relatedCommunityItm;
					parent.communityItm = communityItm.communityItm;
					parent.communityId = communityItm.communityItm.getID();
				}
				parent.id = parent.getID();

				if (parent.identityItem)
					parent.userItm = SSVC.ArasHelper.getUserHelper().findUserByIdentityId(parent.identityItem.getID());

				if (getChilds)
				{
					if (parent.getProperty("children_count", "0") == "0")
					{
						parent.childs = [];
						continue;
					}
					var childs = new SecureMessageItem("get");
					childs.setProperty("parent_id", parent.id);
					childs.setAttribute("select", "classification, parent_id, message_text, from_identity, to_identity, sent, thumbnail, snapshot, source_major_rev, source_generation, source_state, source_id, markup, history_item, last_reply_sent, children_count, view_state");
					if (childsCount)
						childs.setAttribute("maxRecords", childsCount);
					childs.setAttribute("orderBy", "sent asc");
					childs.fill();

					childs.buildStructure(false);
					parent.childs = (childs.itemStructure) ? childs.itemStructure : [];
				}
			}
		};

		function sortMessagesByFirstName(messageObj1, messageObj2)
		{
			var userItm1 = messageObj1.userItm;
			var userItm2 = messageObj2.userItm;

			var firstName1 = (userItm1 != null) ? userItm1.getProperty("first_name") : "";
			var firstName2 = (userItm1 != null) ? userItm2.getProperty("first_name") : "";

			if (firstName1 > firstName2) return 1;
			if (firstName1 < firstName2) return -1;
			return 0;
		}

		function sortMessagesByLastName(messageObj1, messageObj2)
		{
			var userItm1 = messageObj1.userItm;
			var userItm2 = messageObj2.userItm;

			var lastName1 = (userItm1 != null) ? userItm1.getProperty("last_name") : "";
			var lastName2 = (userItm1 != null) ? userItm2.getProperty("last_name") : "";

			if (lastName1 > lastName2) return 1;
			if (lastName1 < lastName2) return -1;
			return 0;
		}

		function sortMessagesByMessage(messageObj1, messageObj2)
		{
			var message1 = messageObj1.getProperty("message_text").toLowerCase();
			var message2 = messageObj2.getProperty("message_text").toLowerCase();;
			if (message1 > message2) return 1;
			if (message1 < message2) return -1;
			return 0;
		}

		function sortMessagesByConversation(messageObj1, messageObj2)
		{
			var date1 = messageObj1.getProperty("last_reply_sent", messageObj1.getProperty("sent"));
			var date2 = messageObj2.getProperty("last_reply_sent", messageObj2.getProperty("sent"));
			if (date1 > date2) return -1;
			if (date1 < date2) return 1;
			return 0;
		}

		function sortMessagesByDate(messageObj1, messageObj2)
		{
			var date1 = messageObj1.getProperty("sent");
			var date2 = messageObj2.getProperty("sent");
			if (date1 > date2) return -1;
			if (date1 < date2) return 1;
			return 0;
		}

		function sortMessagesByMarkupExistent(messageObj1, messageObj2)
		{
			var message1 = messageObj1.getProperty("snapshot", null);
			var message2 = messageObj2.getProperty("snapshot", null);
			if (!message1 && !message2) return 0;
			if (message1 && !message2) return -1;
			if (!message1 && message2) return 1;
			return 0;
		}

		function sortMessagesByItem(messageObj1, messageObj2)
		{
			//Get item from community
			var itm1 = messageObj1.relatedItm;
			var itm2 = messageObj2.relatedItm;

			if (SSVC.Utils.isNullOrUndefined(itm1) || SSVC.Utils.isNullOrUndefined(itm2))
				return 0;

			//Compare by itemtype name
			var itemTypeName1 = itm1.getType();
			var itemTypeName2 = itm2.getType();

			if (itemTypeName1 != itemTypeName2)
			{
				if (itemTypeName1 > itemTypeName2)
					return 1;
				else
					return -1;
			}

			//Compare by item keyed_name
			var itemKeyedName1 = itm1.getProperty("keyed_name");
			var itemKeyedName2 = itm2.getProperty("keyed_name");

			if (itemKeyedName1 != itemKeyedName2)
			{
				if (itemKeyedName1 > itemKeyedName2)
					return 1;
				else
					return -1;
			}

			//Compare by date
			var date1 = messageObj1.getProperty("sent");
			var date2 = messageObj2.getProperty("sent");

			if (date1 != date2)
			{
				if (date1 > date2)
					return 1;
				else
					return -1;
			}

			return 0;
		}

		return secureMessageItm;
	}

	var communityItem = function()
	{
		var dictionary = {};

		this.getById = function(id)
		{
			return getById(id);
		};

		this.new = function(itemtype_id, item_id)
		{
			var communityItm = top.aras.newIOMItem("Community", "add");
			communityItm.setProperty("itemtype_id", itemtype_id);
			communityItm.setProperty("item_id", item_id);
			communityItm = communityItm.apply();

			if (communityItm.isError())
			{
				top.aras.AlertError(communityItm.getErrorString());
				return "";
			}
			addToDictionary(communityItm);
			var cmnty = getById(communityItm.getID());

			return cmnty;
		}

		function getById(id)
		{
			var result = dictionary[id];
			if (result) return result;

			var communityItms = top.aras.newIOMItem("Community", "get");

			if (id)
				communityItms.setID(id);

			communityItms.setAttribute("select", "itemtype_id, item_id");
			communityItms.setPropertyItem("itemtype_id", top.aras.newIOMItem("ItemType", "get"));
			communityItms = communityItms.apply();

			if (communityItms.isError())
			{
				return null;
			}

			for (var i = 0; i < communityItms.getItemCount() ; i++)
			{
				var communityItm = communityItms.getItemByIndex(i);
				addToDictionary(communityItm);
				return dictionary[communityItm.getID()];
			}
		}

		this.getByItemId = function(id)
		{
			var communityItms = top.aras.newIOMItem("Community", "get");

			communityItms.setProperty("item_id", id);

			communityItms.setAttribute("select", "itemtype_id, item_id");
			communityItms.setPropertyItem("itemtype_id", top.aras.newIOMItem("ItemType", "get"));
			communityItms = communityItms.apply();

			if (communityItms.isError())
			{
				return null;
			}

			for (var i = 0; i < communityItms.getItemCount() ; i++)
			{
				var communityItm = communityItms.getItemByIndex(i);
				addToDictionary(communityItm);
				return dictionary[communityItm.getID()];
			}
		};

		function addToDictionary(communityItm)
		{
			var itemTypeId = communityItm.getProperty("itemtype_id");
			var itemConfigId = communityItm.getProperty("item_id");

			//Get related item
			var relatedCommunityItm = top.aras.newIOMItem(top.aras.getItemTypeName(itemTypeId), "get");
			relatedCommunityItm.setProperty("config_id", itemConfigId);
			relatedCommunityItm.setAttribute("select", "keyed_name, config_id, major_rev, generation, state, view_file");
			relatedCommunityItm = relatedCommunityItm.apply();

			if (relatedCommunityItm.isError())
				return false;

			var fileItm = null;

			if (relatedCommunityItm.getType() == "Document")
			{
				var aml =
						"<AML>" +
							"<Item type='Document' action='get' id='" + relatedCommunityItm.getID() + "' select='id'>" +
								"<Relationships>" +
									"<Item type='Document File' action='get' orderBy='sort_order' maxRecords='1' select='related_id(filename)'>" +
										"<related_id>" +
											"<Item type='File' action='get' select='filename,mimetype'>" +
											"</Item>" +
										"</related_id>" +
									"</Item>" +
								"</Relationships>" +
							"</Item>" +
						"</AML>";

				var documentItem = top.aras.IomInnovator.newItem("Document");
				documentItem.loadAML(aml);
				documentItem = documentItem.apply();

				if (!documentItem.isError())
					fileItm = documentItem.getItemsByXPath("Relationships/Item/related_id/Item");
			}

			if (relatedCommunityItm.getType() == "CAD")
			{
				if (relatedCommunityItm.getProperty("view_file", "") != "")
				{
					fileItm = top.aras.IomInnovator.newItem("File", "get");
					fileItm.setID(relatedCommunityItm.getProperty("view_file"));
					fileItm.setAttribute("select", "filename, mimetype");
					fileItm = fileItm.apply();

					if (fileItm.isError())
						fileItm = null;
				}
			}

			dictionary[communityItm.getID()] = {
				communityItm: communityItm,
				relatedCommunityItm: relatedCommunityItm,
				fileItm: fileItm
			};
		}
	};

	SecureMessageItem.CommunityItem = new communityItem();

	delete SecureMessageItem;

	var ArasHelper = function()
	{
		var userHelper = null;

		var result =
			{
				SecureMessage: SecureMessageItem,

				getSecureMessages: function(page, size, orderBy)
				{
					//settings.aml = SecureMessage.AmlStrings.TopSecureMessages.Format(settings.orderBy, settings.sortOder, settings.page, settings.size);
					var itms = new SSVC.ArasHelper.SecureMessage("get");
					itms.setPropertyAttribute("parent_id", "condition", "is null");
					itms.setAttribute("select", "classification, parent_id, message_text, from_identity, to_identity, sent, thumbnail, snapshot, source_major_rev, source_generation, source_state, source_id, markup, history_item, last_reply_sent, children_count, view_state");
					itms.setAttribute("page", page);
					itms.setAttribute("size", size);
					itms.setAttribute("orderBy", orderBy);
					itms.fill();
					itms.buildStructure(true, 3);
					if (itms.isError())
						return null;

					return itms;
				},

				newSecureMessage: function(textContent, parent_id, source_id, from_identity, type)
				{
					var secureMessage = new SSVC.ArasHelper.SecureMessage("add");

					secureMessage.setProperty("parent_id", parent_id);
					secureMessage.setProperty("source_id", source_id);

					secureMessage.setProperty("message_text", textContent);
					secureMessage.setProperty("classification", type);

					secureMessage.setPropertyItem("from_identity", from_identity);
					secureMessage.fill();
					secureMessage.buildStructure(false);
					return secureMessage;
				},

				getUserHelper: function()
				{
					if (userHelper == null)
						userHelper = new SSVC.UserHelper()
					return userHelper;
				},

				getCurrentIdentityId: function()
				{
					var userNd = top.aras.getLoggedUserItem();
					var identityNd = userNd.selectSingleNode("Relationships/Item[@type='Alias']/related_id/Item[@type='Identity']");
					if (!identityNd) return "";
					return identityNd.getAttribute("id");
				},

				//Get file url by vault id
				getFileUrlByFileId: function(vaultUrl)
				{
					try
					{
						var fileId = vaultUrl.replace(/vault:\/\/\/\?fileid\=/i, "");
						return top.aras.IomInnovator.getFileUrl(fileId, top.Enums.UrlType.SecurityToken);
					}
					catch (e)
					{
						return "";
					}
				},

				getResultFromServer: function(methodName, params)
				{
					//var res = top.aras.newItem("Method");
					var res = top.aras.newIOMItem("Method");
					res.setAttribute("action", methodName);
					res.setProperty("params", params);
					res = res.apply();
					return res.getResult();

				},

				startProgress: function()
				{
					top.aras.showStatusMessage("status", "", "../images/Progress.gif");
				},

				endProgress: function()
				{
					top.aras.showStatusMessage("status", "Ready", "");
				},
			}

		return result;
	};

	return new ArasHelper();
})());
